﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CarShop.Domain.Entities;
using CarShop.Domain.Interfaces;
using CarShop.Domain.Interfaces.Repositories;
using CarShop.Services.Contracts.Interfaces;

namespace CarShop.Services
{
    public class CarService : ServiceBase, ICarService
    {
        private readonly ICarRepository _carRepository;
        private readonly ICarStatusRepository _carStatusRepository;

        public CarService(IUnitOfWork unitOfWork, ICarRepository carRepository, ICarStatusRepository carStatusRepository) : base(unitOfWork)
        {
            _carRepository = carRepository;
            _carStatusRepository = carStatusRepository;
        }

        public IEnumerable<Car> GetCars(Func<Car, bool> predicate, int page, int countOnPage, out int totalPages)
        {
            IEnumerable<Car> result = _carRepository.GetPaged(predicate, page, countOnPage, out totalPages,
                c => c.CreationDate, false, null);

            return result;
        }

        public IEnumerable<Car> GetNotSoldCars(Func<Car, bool> predicate, int page, int countOnPage, out int totalPages)
        {
            IEnumerable<int> notSoldStatuses = _carStatusRepository.GetAll()
                .Where(s => s.Name == CarStatus.NameFor.InStorage
                            || s.Name == CarStatus.NameFor.Delivering)
                            .Select(s => s.Id);

            Func<Car, bool> newPredicate = (c) => c.OrderId == null && notSoldStatuses.Contains(c.CarStatusId) && predicate(c);

            IEnumerable<Car> result = _carRepository.GetPaged(newPredicate, page, countOnPage, out totalPages,
                c => c.CreationDate, false, null);

            return result;
        }

        public bool AddCar(Car car)
        {
            bool result = false;

            try
            {
                _carRepository.Add(car);
                _unitOfWork.Commit();

                result = true;
            }
            catch
            {

            }

            return result;
        }

        public bool UpdateCar(Car car)
        {
            bool result = false;

            try
            {
                _carRepository.Update(car);
                _unitOfWork.Commit();

                result = true;
            }
            catch
            {

            }

            return result;
        }

        public Car GetCar(int id)
        {
            Car result = _carRepository.Get(id);
            return result;
        }

        public Car GetCarWithAllInfo(int id)
        {
            Car result = _carRepository.GetAll("Order", "CarStatus", "CarBrand", "CarType")
                .SingleOrDefault(c => c.Id == id);

            return result;
        }
    }
}
